#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#define maxn 100005
using namespace std;

int n, m, L[maxn], R[maxn], p[maxn], D[maxn], V[maxn], A[maxn];

inline int nxt(int pos)
{
    return lower_bound(p, p + m, pos) - p;
}

inline int prv(int pos)
{
    return upper_bound(p, p + m, pos) - p - 1;
}

inline int ceildiv(int x, int y)
{
    return x % y == 0? x / y: x / y + 1;
}

int main()
{
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int T;
    cin >> T;
    while(T--)
    {
        int l, lim;
        cin >> n >> m >> l >> lim;
        for(int i=0; i<n; i++)
            cin >> D[i] >> V[i] >> A[i];
        for(int i=0; i<m; i++)
            cin >> p[i];
        l = p[m - 1];
        for(int i=0; i<n; i++)
        {
            int d = D[i], v = V[i], a = A[i];
            L[i] = m, R[i] = 0;
            if(d > l) continue; 
            if(a == 0)
                if(v <= lim) L[i] = m;
                else L[i] = nxt(d), R[i] = m - 1;
            else if(a < 0)
                if(v <= lim) L[i] = m;
                else L[i] = nxt(d), R[i] = prv(d + ceildiv(v * v - lim * lim, -2 * a) - 1);
            else // a > 0
                if(v > lim) L[i] = nxt(d), R[i] = m - 1;
                else L[i] = nxt(d + (lim * lim - v * v) / (2 * a) + 1), R[i] = m - 1;
        }
        vector<pair<int, int>> v;
        for(int i=0; i<n; i++)
            if(L[i] <= R[i])
                v.emplace_back(R[i], L[i]);
        sort(v.begin(), v.end());
        set<int> s;
        s.insert(m);
        for(auto& seg: v)
        {
            int r = seg.first, l = seg.second;
            if(*s.lower_bound(l) > r)
                s.insert(r);
        }
        cout << v.size() << ' ' << m - (s.size() - 1) << '\n';
    }
    return 0;
}